"""
邢不行｜策略分享会
选币策略框架𝓟𝓻𝓸

版权所有 ©️ 邢不行
微信: xbx1717

本代码仅供个人学习使用，未经授权不得复制、修改或用于商业用途。

Author: 邢不行
"""

import warnings
import time

import pandas as pd

from config import raw_data_path
from core.backtest import run_backtest, step4_select_coins, step5_aggregate_select_results, step6_simulate_performance
from core.model.backtest_config import BacktestConfig
from core.utils.log_kit import logger
from core.version import version_prompt

# ====================================================================================================
# ** 脚本运行前配置 **
# 主要是解决各种各样奇怪的问题，确保脚本能在不同环境下正常运行
# ====================================================================================================
warnings.filterwarnings('ignore')  # 过滤掉所有的warnings，以避免不必要的警告信息干扰用户

# pandas相关的显示设置，优化控制台输出
pd.set_option('display.max_rows', 1000)  # 设置DataFrame显示的最大行数为1000
pd.set_option('expand_frame_repr', False)  # 当列数超过屏幕宽度时，不自动换行
pd.set_option('display.unicode.ambiguous_as_wide', True)  # 处理模糊宽度字符的显示，使列对齐更美观
pd.set_option('display.unicode.east_asian_width', True)  # 处理东亚字符宽度，确保在命令行输出时的表格对齐


if __name__ == '__main__':
    version_prompt()  # 输出当前版本信息
    logger.info(f'系统启动中，稍等...')

    r_time = time.time()  # 记录当前时间戳，用于后续计算耗时

    # 从配置文件中初始化回测配置
    backtest_config = BacktestConfig.init_from_config()

    # 输出回测配置信息，便于确认当前设置
    backtest_config.info()

    # ====================================================================================================
    # 4. 选币
    # - 根据计算的因子进行选币，筛选出符合条件的加密货币
    # - 选币结果将被保存到硬盘，以便后续分析或复现
    # ====================================================================================================
    step4_select_coins(backtest_config)  # 执行选币操作，将结果保存以供后续使用

    # ====================================================================================================
    # 5. 整理选币结果并形成目标持仓
    # - 对选币结果进行汇总，生成买入或卖出的目标持仓比例
    # ====================================================================================================
    df_spot_ratio, df_swap_ratio = step5_aggregate_select_results(backtest_config, save_final_result=True)  # 汇总选币结果，形成现货和合约的目标持仓
    # logger.ok(f'目标持仓信号已完成，花费时间：{(time.time() - r_time):.3f}秒')  # 记录目标持仓计算完成的时间

    # ====================================================================================================
    # 6. 根据目标持仓计算资金曲线
    # - 使用目标持仓对资金进行模拟回测，生成资金曲线
    # - 回测过程中可以选择是否显示绘图
    # ====================================================================================================
    pivot_dict_spot = pd.read_pickle(raw_data_path / 'market_pivot_spot.pkl')  # 读取现货市场的枢纽点数据
    pivot_dict_swap = pd.read_pickle(raw_data_path / 'market_pivot_swap.pkl')  # 读取合约市场的枢纽点数据
    step6_simulate_performance(
        backtest_config,
        df_spot_ratio,
        df_swap_ratio,
        pivot_dict_spot,
        pivot_dict_swap,
        if_show_plot=True
    )  # 根据目标持仓计算资金曲线，并显示图表（可选）
    logger.info(f'回测结果存储在: {backtest_config.get_result_folder()}')

    logger.ok(f'完成回测，累计消耗时间：{time.time() - r_time:.3f}秒')  # 记录整个回测过程的总耗时
